from uuid import UUID

from sqlalchemy import desc

from .base_service import BaseService
from injector import inject
from dataclasses import dataclass
from pkg.sqlalchemy import SQLAlchemy
from internal.schema import DatasetSchema, DatasetWithPageReq
from ..model import DataSet
from internal.exception import ValidateErrorException, NotFoundException
from pkg.pageinator import Pageinator
from internal.entity import DEFAULT_DESCRIPTION_FORMAT


@inject
@dataclass
class DatasetService(BaseService):
    db: SQLAlchemy

    def created_dataset(self, data: DatasetSchema) -> DataSet:
        dataset = self.db.session.query(DataSet).filter_by(
            name=data.name.data
        ).one_or_none()
        if dataset is not None:
            raise ValidateErrorException(f"该{data.name.data}知识库已存在")
        if not data.description.data:
            data.description.data = DEFAULT_DESCRIPTION_FORMAT.format(name=data.name.data)
        res = self.create(
            DataSet,
            name=data.name.data,
            icon=data.icon.data,
            description=data.description.data
        )
        return res

    def get_dataset(self, dataset_id: UUID) -> DataSet:
        dataset = self.get(DataSet, dataset_id)
        if dataset is None:
            raise NotFoundException("该知识库不存在")
        return dataset

    def update_dataset(self, dataset_id: UUID, data: DatasetSchema) -> DataSet:
        dataset = self.get(DataSet, dataset_id)
        if not dataset:
            raise ValidateErrorException(f"该{data.name.data}知识库不存在")
        model = self.update(dataset,
                            name=data.name.data,
                            icon=data.icon.data,
                            description=data.description.data
                            )
        return model

    def dataset_with_page(self, req: DatasetWithPageReq) -> tuple[list[DataSet], Pageinator]:
        pageinator = Pageinator(self.db, req)
        serch = []
        if req.serch_keyword.data is not None:
            serch.append(DataSet.name.ilike(f"%{req.serch_keyword.data}%"))
        data_list = pageinator.paginate(
            self.db.session.query(DataSet).filter(*serch).order_by(desc("created_at"))
        )
        return data_list, pageinator
